package cn.itsource.wechat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.system.UserInfo;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.RedisService;
import cn.itsource.org.domain.LoginInfo;
import cn.itsource.org.domain.User;
import cn.itsource.org.mapper.UserMapper;
import cn.itsource.wechat.domain.*;
import cn.itsource.wechat.mapper.WxUserMapper;
import cn.itsource.wechat.service.IWeChatService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class WeChatServiceImpl implements IWeChatService {

    /**
     * 注入对象，可以拿到yml里面的地址和其他数据
     */
    @Autowired
    private WechartProperties wechartProperties;

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisService redisService;

    @Override
    public String tologin() {
        /**     第一步骤：跳转到扫码页面        */
        //1.获取到那个重定向的地址
        String authorizationCodeUrl = wechartProperties.getAuthorizationCodeUrl();
        //https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect
        log.info(authorizationCodeUrl);

        //2.替换%s
        String appId = wechartProperties.getAppId();
        String redirectUri = wechartProperties.getRedirectUri();
        String state = IdUtil.fastSimpleUUID();
        String url = String.format(authorizationCodeUrl, appId, redirectUri, state);

        //3.重定向
        return "redirect:"+url;
    }

    @Override
    public String callback(String code) {

        /** 第二步骤：回调拿到code，通过code拿到token信息*/

        //1.拿到获取token的url %s
        String tokenUrl = wechartProperties.getTokenUrl();
        //https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code
        log.info(tokenUrl);

        String appId = wechartProperties.getAppId();
        String appSecrect = wechartProperties.getAppSecrect();

        //2.替换%s
        tokenUrl = String.format(tokenUrl, appId, appSecrect, code);
        log.info(tokenUrl);

        //3.发get请求获取结果
        String result = HttpUtil.get(tokenUrl);
        System.out.println(result);

        //4.把json字符串转成对象
        WechatTokenDto wechatTokenDto = JSONObject.parseObject(result, WechatTokenDto.class);
        System.out.println(wechatTokenDto.getAccess_token());

        /** 第三步骤：通过token拿到用户资源（微信用户信息）*/
        //1.拿到userInfo的url
        String userinfoUrl = wechartProperties.getUserinfoUrl();
        String access_token = wechatTokenDto.getAccess_token();
        String openid = wechatTokenDto.getOpenid();
        //2.替换%s
        userinfoUrl = String.format(userinfoUrl,access_token,openid);

        //3.发送get请求获取结果
        String userInfoResult = HttpUtil.get(userinfoUrl);
        System.out.println(userInfoResult);

        //4.转成对象
        WechartUserInfoDto wechartUserInfoDto = JSONObject.parseObject(userInfoResult, WechartUserInfoDto.class);


        String redirectUrl = "http://bugtracker.itsource.cn:8081/binder.html";
        //处理情况1：wxuser没有数据，绝对要去绑定页面
        //1.通过openid查不到数据，
        WxUser dbWxUser = wxUserMapper.selectByOpenid(openid);
        if (dbWxUser == null){
            //1.1wxuser要新增一条数据
            WxUser wxUser = BeanUtil.copyProperties(wechartUserInfoDto, WxUser.class);
            wxUserMapper.insertSelective(wxUser);
            //2.跳转到绑定页面
            return "redirect:"+redirectUrl+"?openid="+openid;
        }

        //情况2：wxuser有，user有，手机号有，绑定关系有，跳转到首页
        //1.通过openid查wxuser表有数据，有外键user_id
        Long userId = dbWxUser.getUser_id();
        //2.通过user_id查询user表，有数据，并且有手机号
        if (userId != null){
            User user = userMapper.selectByPrimaryKey(userId);
            if (user != null && StringUtils.isNotBlank(user.getPhone())){


                //3.完成往redis里面存token 和用户信息
                String token = IdUtil.fastSimpleUUID();
                LoginInfo loginInfo = BeanUtil.copyProperties(user, LoginInfo.class);
                //todo 我王天霸今天心情不好就写10% 明天我继续写
                loginInfo.setUserId(user.getId());
                loginInfo.setToken(token);

                //4.存redis
                redisService.setStringKeyAndValue(token,loginInfo,30);

                //3.跳转到首页
                return "redirect:http://bugtracker.itsource.cn:8081/index.html?token="+token
                        +"&username="+StringUtils.defaultIfBlank(user.getUsername(),"")+"&email="+StringUtils.defaultIfBlank(user.getEmail(),"")+
                        "&phone="+StringUtils.defaultIfBlank(user.getPhone(),"");
            }
        }

        //其他情况：统统直接去绑定页面
        return "redirect:"+redirectUrl+"?openid="+openid;
    }

    public static void main(String[] args) {
        String a = null;

        System.out.println(a+"xxxx");

        String s = StringUtils.defaultIfBlank(a, "");
        System.out.println(s);

    }

    @Override
    public AjaxResult binder(BinderDto binderDto) {

        //验证code，从redis里面拿，比对

        //根据user表是否有数据做不同的操作
        //1.如果user通过手机号查不到，要新增
        User dbUser = userMapper.selectByPhone(binderDto.getPhone());

        Long userId = null;
        User redisUser = null;
        if (dbUser == null){
            //1.1拼装user对象
            User user = new User();
            user.setPhone(binderDto.getPhone());
            user.setPassword("123");
            //1.1加盐加密
            user.init();
            userMapper.insertSelective(user);

            userId = user.getId();
            redisUser = user;
        }else {
            userId = dbUser.getId();
            redisUser = dbUser;
        }

        //维护两张表的关系
        //1.根据openid查询到微信user对象
        WxUser wxUser = wxUserMapper.selectByOpenid(binderDto.getOpenid());
        //1.1把user_id设置给wxUser关联上
        wxUser.setUser_id(userId);

        //2.进行更新，为了把外键关联上
        wxUserMapper.updateByPrimaryKeySelective(wxUser);

        //3.完成往redis里面存token 和用户信息
        String token = IdUtil.fastSimpleUUID();
        LoginInfo loginInfo = BeanUtil.copyProperties(redisUser, LoginInfo.class);
        //todo 插眼
        loginInfo.setUserId(userId);
        loginInfo.setToken(token);

        //4.存redis
        redisService.setStringKeyAndValue(token,loginInfo,30);

        //5.返回数据
        return AjaxResult.createSuccess(loginInfo);
    }


}
